package ks.client.controllers.requests;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ks.client.UserContext;
import ks.client.controllers.commands.IconListCommandController;
import ks.client.controllers.commands.PluginListCommandController;
import ks.client.gui.UMGUI3;
import ks.client.lobby.Lobby;
import ks.framework.common.Message;
import ks.framework.interfaces.IProcessMessage;
import ks.managers.user.User;
import ks.managers.user.UserManager;

/**
 * Controller to process CONNECTING requests from the server that contain the 
 * clients that are logging into the system.
 * <p>
 * Note this may be called when a client logs in initially or when new players join
 * the kombat solitaire system.
 * 
 * @author George Heineman
 * @author Jennifer Hunt
 * @author Christopher Page
 */
public class ConnectingController implements IProcessMessage {

	/** In case we need to process something. */
	Lobby lobby;
	
	/** Construct controller with lobby. */
	public ConnectingController(Lobby lobby) {
		this.lobby = lobby;
		System.out.println("YOU HAVE ACCESSED THE CONNECTING_CONTROLLER");
	}

	/**
	 * Client has received CONNECTING message. Process it.
	 * 
	 * <connecting>
     *   <player name="george" rating="1992" icon="stylish"/>
     *   <player name="admin" rating="1833" icon="ghoulish"/>
     * </connecting>
     * 
	 * @param m The message to process.
	 * @return true on success; false on failure.
	 */
	public boolean process(Message m) {
		// Get our context
		UserContext context = lobby.getUserContext();
		
		// Get usermanager instance
		UserManager uman = context.getUserManager();
		
		// get usermanager gui instance
		UMGUI3 gui = lobby.getUMGUI3();
		
		// extract information from the message
		Node connecting = m.contents();
		
		// get child nodes of connecting node
		NodeList playersList = connecting.getChildNodes();
		
		// temporary nodes created here (for efficiency)
		Node playerNode, nameNode, ratingNode, iconNode, adminNode;
		NamedNodeMap nnpTmp;
		User uTmp;
		
		// get players and related info from playerList and add it
		for (int i = 0; i < playersList.getLength(); i++) {
			playerNode = playersList.item(i);
			
			// if playerNode is null, skip to next loop iteration
			if (playerNode == null)
				continue;
			
			// if playerNode is not a player element, skip to next loop iteration
			if (!playerNode.getNodeName().equals("player"))
				continue;
			
			// get list of player element's attributes
			nnpTmp = playerNode.getAttributes();
			
			// get player element's attributes
			nameNode = nnpTmp.getNamedItem("name");
			ratingNode = nnpTmp.getNamedItem("rating");
			iconNode = nnpTmp.getNamedItem("icon");
			adminNode = nnpTmp.getNamedItem("admin");
			
			// if name attribute is null, skip to next loop iteration
			if (nameNode == null) {
				continue;
			}
			// otherwise, create a new user with that name
			else {
				uTmp = uman.getUser(nameNode.getNodeValue());
				if (uTmp == null)
					uTmp = new User(nameNode.getNodeValue(), "");
			}
			// if a rating is provided, set that user's rating
			if (ratingNode != null){
				uTmp.setRating(Integer.parseInt(ratingNode.getNodeValue()));
			}
			// if an icon is provided, set that player's icon
			if (iconNode != null){
				uTmp.setIconName(iconNode.getNodeValue());
			}
			if (adminNode != null) {
				uTmp.setAdmin(Boolean.parseBoolean(adminNode.getNodeValue()));
			}
			
			if (uman.getUser(nameNode.getNodeValue()) == null)
				uman.addUser(uTmp);
			
			// add user to gui instance
			gui.addUser(uTmp);
			gui.refreshTable();
		}
		
		new IconListCommandController(lobby).send();
		new PluginListCommandController(lobby).send();
		// success
		return true;
	}
}
